<template><div><h2 id="数据填充" tabindex="-1"><a class="header-anchor" href="#数据填充"><span>数据填充</span></a></h2>
<ul>
<li><a href="#introduction">简介</a></li>
<li><a href="#writing-seeders">编写 Seeders</a>
<ul>
<li><a href="#using-model-factories">使用模型工厂</a></li>
<li><a href="#calling-additional-seeders">调用其他 Seeders</a></li>
<li><a href="#muting-model-events">禁用模型事件</a></li>
</ul>
</li>
<li><a href="#running-seeders">运行 Seeders</a></li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p>Laravel 内置了一个可为你的数据库填充测试数据的数据填充类。所有的数据填充类都应该放在 <code v-pre>database/seeds</code> 目录下。Laravel 默认定义了一个 <code v-pre>DatabaseSeeder</code> 类。通过这个类，你可以用 <code v-pre>call</code> 方法来运行其他的 <code v-pre>seed</code> 类，从而控制数据填充的顺序。</p>
<blockquote>
<p><strong>注意</strong><br>
在数据库填充期间，<a href="https://learnku.com/docs/laravel/10.x/eloquentmd#mass-assignment" target="_blank" rel="noopener noreferrer">批量赋值保护</a>被自动禁用。</p>
</blockquote>
<h2 id="编写-seeders" tabindex="-1"><a class="header-anchor" href="#编写-seeders"><span>编写 Seeders</span></a></h2>
<p>运行 <a href="https://learnku.com/docs/laravel/10.x/artisan" target="_blank" rel="noopener noreferrer">Artisan 命令</a> <code v-pre>make:seeder</code> 可以生成 Seeder，生成的 seeders 都放在 <code v-pre>database/seeders</code> 目录下：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan make:seeder UserSeeder</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>一个数据填充类默认只包含一个方法：<code v-pre>run</code> ，当执行 <code v-pre>db:seed</code> <a href="https://learnku.com/docs/laravel/10.x/artisan" target="_blank" rel="noopener noreferrer">Artisan命令</a> 时，被调用。在 <code v-pre>run</code> 方法中, 可以按需将数据插入数据库中。 也可以使用<a href="https://learnku.com/docs/laravel/10.x/queries" target="_blank" rel="noopener noreferrer">查询构造器</a>来手动插入数据，或者可以使用 <a href="https://learnku.com/docs/laravel/10.x/eloquent-factories" target="_blank" rel="noopener noreferrer">Eloquent 数据工厂</a>。</p>
<p>例如，在默认 <code v-pre>DatabaseSeeder</code> 类的 <code v-pre>run</code> 方法中添加一个数据库插入语句：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">Database<span class="token punctuation">\</span>Seeders</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Seeder</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Hash</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Str</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">DatabaseSeeder</span> <span class="token keyword">extends</span> <span class="token class-name">Seeder</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 运行数据填充</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">insert</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token class-name static-context">Str</span><span class="token operator">::</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'email'</span> <span class="token operator">=></span> <span class="token class-name static-context">Str</span><span class="token operator">::</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token operator">.</span><span class="token string single-quoted-string">'@gmail.com'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'password'</span> <span class="token operator">=></span> <span class="token class-name static-context">Hash</span><span class="token operator">::</span><span class="token function">make</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'password'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
可以在 <code v-pre>run</code> 方法的参数中键入你需要的任何依赖性,它们将自动通过 Laravel <a href="https://learnku.com/docs/laravel/10.x/container" target="_blank" rel="noopener noreferrer">服务容器</a>注入。</p>
</blockquote>
<h3 id="使用模型工厂" tabindex="-1"><a class="header-anchor" href="#使用模型工厂"><span>使用模型工厂</span></a></h3>
<p>当然，手动指定每个模型填充的属性是很麻烦的。因此可以使用 <a href="https://learnku.com/docs/laravel/10.x/eloquent-factories" target="_blank" rel="noopener noreferrer">Eloquent 数据工厂</a>来更方便地生成大量的数据库记录。首先，查看 <a href="https://learnku.com/docs/laravel/10.x/eloquent-factories" target="_blank" rel="noopener noreferrer">Eloquent 数据工厂</a>，了解如何定义工厂。</p>
<p>例如，创建50个用户，每个用户有一个相关的帖子：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>User</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 运行数据库迁移</span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token function">factory</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">            <span class="token operator">-></span><span class="token function">count</span><span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">)</span></span>
<span class="line">            <span class="token operator">-></span><span class="token function">hasPosts</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span></span>
<span class="line">            <span class="token operator">-></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="调用其他-seeders" tabindex="-1"><a class="header-anchor" href="#调用其他-seeders"><span>调用其他 Seeders</span></a></h3>
<p>在 <code v-pre>DatabaseSeeder</code> 类中，可以使用 <code v-pre>call</code> 方法来执行其他的填充类。使用 <code v-pre>call</code> 方法可以将数据库迁移分成多个文件，这样就不会出现单个数据填充类过大。<code v-pre>call</code> 方法接受一个由数据填充类组成的数组：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 运行数据库迁移</span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">call</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">        <span class="token class-name static-context">UserSeeder</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token class-name static-context">PostSeeder</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token class-name static-context">CommentSeeder</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="禁用模型事件" tabindex="-1"><a class="header-anchor" href="#禁用模型事件"><span>禁用模型事件</span></a></h3>
<p>在运行时，你可能想阻止模型调用事件，可以使用 <code v-pre>WithoutModelEvents</code> 特性。使用 <code v-pre>WithoutModelEvents</code> trait 可确保不调用模型事件，即使通过 <code v-pre>call</code> 方法执行了额外的 seed 类：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">Database<span class="token punctuation">\</span>Seeders</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Seeder</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Console<span class="token punctuation">\</span>Seeds<span class="token punctuation">\</span>WithoutModelEvents</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">DatabaseSeeder</span> <span class="token keyword">extends</span> <span class="token class-name">Seeder</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">use</span> <span class="token package">WithoutModelEvents</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 运行数据库迁移</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">call</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">            <span class="token class-name static-context">UserSeeder</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="运行-seeders" tabindex="-1"><a class="header-anchor" href="#运行-seeders"><span>运行 Seeders</span></a></h2>
<p>执行 <code v-pre>db:seed</code> Artisan 命令来为数据库填充数据。默认情况下，<code v-pre>db:seed</code> 命令会运行 <code v-pre>Database\Seeders\DatabaseSeeder</code> 类来调用其他数据填充类。当然，也可以使用 <code v-pre>--class</code> 选项来指定一个特定的填充类：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan db:seed</span>
<span class="line"></span>
<span class="line">php artisan db:seed <span class="token parameter variable">--class</span><span class="token operator">=</span>UserSeeder</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你还可以使用 <code v-pre>migrate:fresh</code> 命令结合 <code v-pre>--seed</code> 选项，这将删除数据库中所有表并重新运行所有迁移。此命令对于完全重建数据库非常有用。 <code v-pre>--seeder</code> 选项可以用来指定要运行的填充文件：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan migrate:fresh <span class="token parameter variable">--seed</span></span>
<span class="line"></span>
<span class="line">php artisan migrate:fresh <span class="token parameter variable">--seed</span> <span class="token parameter variable">--seeder</span><span class="token operator">=</span>UserSeeder </span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="在生产环境中强制运行填充" tabindex="-1"><a class="header-anchor" href="#在生产环境中强制运行填充"><span>在生产环境中强制运行填充</span></a></h4>
<p>一些填充操作可能会导致原有数据的更新或丢失。为了保护生产环境数据库的数据，在 <code v-pre>生产环境</code> 中运行填充命令前会进行确认。可以添加 <code v-pre>--force</code> 选项来强制运行填充命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan db:seed <span class="token parameter variable">--force</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p>本译文仅用于学习和交流目的，转载请务必注明文章译者、出处、和本文链接<br>
我们的翻译工作遵照 <a href="https://learnku.com/docs/guide/cc4.0/6589" target="_blank" rel="noopener noreferrer">CC 协议</a>，如果我们的工作有侵犯到您的权益，请及时联系我们。</p>
</blockquote>
<hr>
<blockquote>
<p>原文地址：<a href="https://learnku.com/docs/laravel/10.x/seeding/14886" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/10.x/se...</a></p>
<p>译文地址：<a href="https://learnku.com/docs/laravel/10.x/seeding/14886" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/10.x/se...</a></p>
</blockquote>
</div></template>


